package dev.ece.suit.loader.models.dae;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang3.StringUtils;

import dev.ece.suit.loader.models.dae.DAEGeometries.Input;
import dev.ece.util.lib.Matrix4f;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="library_animations")
public class DAEAnimations {

	@XmlElement
	private Animation[] animation;
	
	public Map<String, Animation> toAnimationMap() {
		Map<String, Animation> map = new ConcurrentHashMap<String, Animation>();
		if(this.animation != null) {
			for(Animation animation: this.animation) {
				map.put(animation.getName(), animation);
			}
		}
		return map;
	}
	
	public Animation[] getAnimation() {
		return animation;
	}

	public void setAnimation(Animation[] animation) {
		this.animation = animation;
	}

	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="animation")
	public static class Animation {
		
		@XmlAttribute
		private String id;
		
		@XmlAttribute
		private String name;
		
		@XmlElement
		private DAEGeometries.Source[] source;
		
		@XmlElement
		private Sampler sampler;
		
		@XmlElement
		private Animation animation;

		public DAEKeyFrame[] toDAEKeyFrames() throws IOException {
			if(sampler != null && sampler.getInput() != null && source != null) {
				Map<String, DAEGeometries.Source> map = toSourceMap();
				Input[] inputs = sampler.getInput();
				DAEGeometries.Source[] sources = new DAEGeometries.Source[2];
				for(Input input: inputs) {
					if(StringUtils.equals(DAE.INPUT, input.getSemantic())) {
						sources[0] = map.get(input.getSource());
					} else if(StringUtils.equals(DAE.OUTPUT, input.getSemantic())) {
						sources[1] = map.get(input.getSource());
					}
				}
				float[] times = sources[0].toFloatArray();
				Matrix4f[] matrixs = sources[1].toMatrix4fArray();
				DAEKeyFrame[] keyFrames = new DAEKeyFrame[times.length];
				for(int i=0; i<times.length; i++) {
					keyFrames[i] = new DAEKeyFrame(times[i], matrixs[i]);
				}
				return keyFrames.length > 0 ? keyFrames : null;
			} else if(this.animation != null) {
				return this.animation.toDAEKeyFrames();
			}
			return null;
		}
		
		public Map<String, DAEGeometries.Source> toSourceMap() {
			Map<String, DAEGeometries.Source> map = new ConcurrentHashMap<String, DAEGeometries.Source>();
			for(DAEGeometries.Source source: this.source) {
				map.put(StringUtils.join("#", source.getId()), source);
			}
			return map;
		}
		
		public Animation getAnimation() {
			return animation;
		}

		public void setAnimation(Animation animation) {
			this.animation = animation;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public DAEGeometries.Source[] getSource() {
			return source;
		}

		public void setSource(DAEGeometries.Source[] source) {
			this.source = source;
		}

		public Sampler getSampler() {
			return sampler;
		}

		public void setSampler(Sampler sampler) {
			this.sampler = sampler;
		}
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="sampler")
	public static class Sampler {
		
		@XmlElement
		private DAEGeometries.Input[] input;

		public DAEGeometries.Input[] getInput() {
			return input;
		}

		public void setInput(DAEGeometries.Input[] input) {
			this.input = input;
		}
		
	}
	
}
